Frontend Forever App
We have a mobile app for you to download and use. And you can unlock many features in the app.
Get it now
Intall Later
Run
HTML
CSS
Javascript
Output
Document
Option 1
Option 2
Option 3
@charset "UTF-8"; @import url(https://fonts.googleapis.com/css?family=Nunito+Sans:300,400,600,700,800); *, :after, :before { box-sizing: border-box; padding: 0; margin: 0; } @import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@1,500&display=swap"); html, body { height: 100%; } body { background-color: #3d3e4a; display: flex; justify-content: center; align-items: center; flex-direction: column; } .container { align-items: center; display: flex; flex-wrap: wrap; justify-content: center; } .radio-btn-group { margin: 10px; } input[type="radio"] { opacity: 0; position: absolute; } input[type="radio"]:checked + label { &::before { box-shadow: 0 0 20px 2px #0763f7; } span { color: #9c092b; } } input[type="radio"]:focus + label { &::before { box-shadow: 0 0 20px 2px #0763f7; } } label { color: #fff; cursor: pointer; display: flex; font-weight: 500; font-style: italic; align-items: center; justify-content: center; font-family: "IBM Plex Mono", monospace; height: 50px; padding: 0 30px; position: relative; &::before { background-color: #24252c; background-image: repeating-linear-gradient( 0deg, #181a29, #181a29 1px, #202436 1px, #202436 2px ); border-radius: 10px; box-shadow: 0 0 0 0 #0763f7; content: ""; height: 100%; position: absolute; left: 0; top: 0; overflow: hidden; transform: skew(-15deg); transition: box-shadow 350ms; width: 100%; z-index: -1; } span { transition: color 350ms; z-index: 1; } svg { border-radius: 10px; overflow: hidden; position: absolute; transform: skew(-15deg); rect { fill: #76b3fa; shape-rendering: crispEdges; } } }
console.log("Event Fired") class RadioButtonEffect { constructor(radioBtnGroups) { this.previousRadioBtn = null; radioBtnGroups.forEach((group) => { const radioBtn = gsap.utils.selector(group)("input[type='radio']")[0]; const nodes = this.getNodes(radioBtn); radioBtn.addEventListener("change", () => { if (this.previousRadioBtn && this.previousRadioBtn !== radioBtn) { this.changeEffect(this.getNodes(this.previousRadioBtn), false); } this.changeEffect(nodes, true); this.previousRadioBtn = radioBtn; }); }); } getNodes(radioBtn) { const container = radioBtn.closest(".radio-btn-group"); return gsap.utils.shuffle(gsap.utils.selector(container)("rect")); } changeEffect(nodes, isChecked) { gsap.to(nodes, { duration: 0.8, ease: "elastic.out(1, 0.3)", x: isChecked ? "100%" : "-100%", stagger: 0.01, overwrite: true }); gsap.fromTo( nodes, { fill: "#0c79f7" }, { fill: "#76b3fa", duration: 0.1, ease: "elastic.out(1, 0.3)", repeat: -1 } ); if (isChecked) { const randomNodes = nodes.slice(0, 3); gsap.to(randomNodes, { duration: 0.7, ease: "elastic.out(1, 0.1)", x: "100%", stagger: 0.1, repeatDelay: 1.5, repeat: -1 }); } } } document.addEventListener("DOMContentLoaded", () => { const radioBtnGroups = document.querySelectorAll(".radio-btn-group"); new RadioButtonEffect(radioBtnGroups); });